#include "Headers/DataAccessors/roomdataaccessor.h"

#include "../../Headers/DataAccessors/typeofroomdataaccessor.h"
#include "../../Headers/DataAccessors/reservationdataaccessor.h"

#include <QDate>
#include <QSqlError>

RoomDataAccessor::RoomDataAccessor(QString databaseName):
    DB(databaseName)
{
}

QSqlRelationalTableModel * RoomDataAccessor::getRooms(const QString filter)
{
    QSqlRelationalTableModel *model = new QSqlRelationalTableModel();
    model->setTable("room");
    model->setRelation(4, QSqlRelation("typeOfRoom", "id", "name"));
    model->insertColumn(5);
    model->setRelation(5, QSqlRelation("typeOfRoom", "id", "cost"));
    if (filter != "")
        model->setFilter(filter);
    model->select();
    return model;
}


bool RoomDataAccessor::setRoom(Room room)
{
    QSqlQuery query(db);
    query.prepare("insert into room (number, name, floor, id_type) values(:number, :name, :floor, :id_type)");
    query.bindValue(":number", room.getNumber());
    query.bindValue(":name", room.getName());
    query.bindValue(":floor", room.getFloor());
    query.bindValue(":id_type", room.getType().getId());
    if (query.exec())
    {
        return true;
    }
    else
    {
        return false;
    }
}

Room * RoomDataAccessor::getRoom(int id)
{
    QSqlQuery query(db);
    if (query.exec("select id, number, name, floor, id_type from room where id = " + QString::number(id)))
    {
        while(query.next())
        {
            int id = query.value(4).toInt();//id тип комнаты
            TypeOfRoomDataAccessor dataType;
            TypeOfRoom *type = dataType.getTypeOfRoom(id);
            Room *room = new Room(
                        query.value(0).toInt(),//id
                        query.value(1).toString(),//number
                        query.value(2).toString(),//name
                        query.value(3).toInt(),//floor
                        *type
                        );
            return room;
        }
    }

    return NULL;
}

bool RoomDataAccessor::deleteRoom(Room room)
{
    QSqlQuery query(db);
    if (query.exec("delete from room where id=" + QString::number(room.getId())))
    {
        return true;
    }
    else
        return false;
}

bool RoomDataAccessor::editRoom(Room room)
{
    QSqlQuery query(db);
    query.prepare("update room set number=:number, name=:name, floor=:floor, id_type=:id_type where id=:id");
    query.bindValue(":id", room.getId());
    query.bindValue(":number", room.getNumber());
    query.bindValue(":name", room.getName());
    query.bindValue(":floor", room.getFloor());
    query.bindValue(":id_type", room.getType().getId());
    if (query.exec())
    {
        return true;
    }
    else
    {
        return false;
    }
}

QSqlQueryModel * RoomDataAccessor::getRoomQueryModel()
{
    QSqlQueryModel * model = new QSqlQueryModel();
    model->setQuery("select room.id, room.number, room.name, room.floor, typeOfRoom.name, typeOfRoom.cost from room, typeOfRoom where room.id_type=typeOfRoom.id", db);
    return model;
}

QSqlQueryModel * RoomDataAccessor::getRoomQueryModelWithFilter(QDate arrivalDate, QDate depertureDate, int count, TypeOfRoom *type)
{
    QSqlQueryModel * model = new QSqlQueryModel();
    QString query = "select room.id, room.number, room.name, room.floor, typeOfRoom.name, typeOfRoom.count, typeOfRoom.cost from room, typeOfRoom where room.id_type=typeOfRoom.id";

    //количество мест
    if (count != 0)
        query += " and typeOfRoom.count>=" + QString::number(count);

    //тип номера
    if (type != NULL)
        query += " and room.id_type=" + QString::number(type->getId());
    model->setQuery(query, db);

    //даты
    QList<int> deleteIndexes;
    ReservationDataAccessor dataReservation;
    for(int i = 0; i < model->rowCount(); i++)
    {
        QSqlQueryModel * reservationModel = new QSqlQueryModel();
        int id_room = model->data(model->index(i,0)).toInt();
        QString reservationQuery = "select reservation.id, reservation.id_room from reservation, room where id_room = " + QString::number(id_room);
        reservationModel->setQuery(reservationQuery, db);

        bool isDelete = false;

        for (int j = 0; j < reservationModel->rowCount(); j++)
        {
            int id_reservation = reservationModel->data(reservationModel->index(j, 0)).toInt();
            Reservation *reserv = dataReservation.getReservation(id_reservation);

            if (arrivalDate >= reserv->getArrivalDate() && arrivalDate < reserv->getDepartureDate())
                isDelete = true;
            if (depertureDate > reserv->getArrivalDate() && depertureDate <= reserv->getDepartureDate())
                isDelete = true;
            if (arrivalDate < reserv->getArrivalDate() && depertureDate > reserv->getDepartureDate())
                isDelete = true;
            if (isDelete)
                break;
        }

        if (isDelete)
        {
            deleteIndexes.push_back(id_room);
        }

        delete reservationModel;
    }

    for(int i = 0; i < deleteIndexes.count(); i++)
    {
        query += " and room.id<>" + QString::number(deleteIndexes[i]);
    }

    model->setQuery(query, db);

    return model;
}

